package game.mapviewer 
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import game.Game;
	import game.map.Army;
	import game.map.Map;
	import game.map.Province;
	import game.mapviewer.commands.SelectProvinceToMoveCommand;
	import game.mapviewer.commands.SelectProvinceToRaidCommand;
	import game.mapviewer.commands.SelectProvinceToSupportCommand;
	import game.mapviewer.popups.PopupsLayer;
	import game.unitmanager.ArmyController;
	/**
	 * ...
	 * @author rnk
	 */
	public class MapViewer extends Sprite
	{
		public var mapInfo:Map;
		public var bg:MovieClip;
		public var spriteHolder:Sprite;
		public var buttonsLayer:Sprite;
		public var provinceHolders:Array = [];
		public var debugSprite:Sprite;
		public var popupsLayer:PopupsLayer;
		public var armies:Array;
		public var papa:Game;
		
		public function MapViewer() 
		{
			
		}
		
		public function Init(map:Map):void
		{
			//info
			mapInfo = map;
			
			//bg
			bg = map.map_bg;
			addChild(bg);
			//debug
			debugSprite = new Sprite();
			addChild(debugSprite);
			
			//armies
			armies = [];
			
			//holders
			spriteHolder = new Sprite();
			addChild(spriteHolder);
			for (var i:int = 0; i < mapInfo.map_info.numChildren; i++)
			{
				var child:DisplayObject = mapInfo.map_info.getChildAt(i);
				var nameinfo:Array = child.name.split("_");
				if (nameinfo[0] == "province")
				{
					var uid:String = nameinfo[1];
					var holder:Sprite = new Sprite();
					holder.x = child.x;
					holder.y = child.y;
					//spriteHolder.addChild(holder);
					
					provinceHolders.push( { uid:uid, sprite:holder } );
				}
			}
			
			//sort province holder by y
			provinceHolders.sort( function (a:Object,b:Object):Number
				{
						var aPrice:Number = a.sprite.y;
						var bPrice:Number = b.sprite.y;
						
						if (aPrice > bPrice) 
						{
							return 1;
						} 
						else 
						if (aPrice < bPrice) 
						{
							return -1;
						} 
						else  
						{
							//aPrice == bPrice
							return 0;
						}					
				}
			);
			for (var j:int = 0; j < provinceHolders.length; j++) 
			{
				spriteHolder.addChild(provinceHolders[j].sprite);
			}
			
			//load units,heroes,armies
			
			
			//buttons layer
			buttonsLayer = new Sprite();
			addChild(buttonsLayer);
			
			//popups layer
			popupsLayer = new PopupsLayer();
			popupsLayer.papa = this;
			addChild(popupsLayer);
			
			//listeners
			SetListeners(true);
			
			
			
		}
		
		private function SetListeners(orly:Boolean):void 
		{
			if (orly)
			{
				bg.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
				bg.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
				bg.addEventListener(MouseEvent.MOUSE_MOVE, OnMouseMove);
			}
		}
		
		
		private function OnMouseDown(e:MouseEvent):void 
		{
			
			startDrag(false, new Rectangle(0, 0, -bg.width + 800, -bg.height + 600));
			Mouse.cursor = MouseCursor.HAND;
		}
		
		private function OnMouseMove(e:MouseEvent):void 
		{
			
		}
		
		private function OnMouseUp(e:MouseEvent):void 
		{
			stopDrag();
			Mouse.cursor = MouseCursor.AUTO;
		}
		
		public function DrawRoutes():void
		{
			debugSprite.graphics.clear();
			var mapOfRoutes:Array = mapInfo.GetRouteMap();
			for (var i:int = 0; i < mapOfRoutes.length-1; i++)
			{
				var provinceHolderA:Sprite = GetProvinceHolder(mapInfo.provinces[i].uid);
				for (var j:int = i+1; j < mapOfRoutes.length; j++)
				{
					
					var provinceHolderB:Sprite = GetProvinceHolder(mapInfo.provinces[j].uid);
					var hasRoute:Boolean = mapOfRoutes[i][j];
					if (hasRoute)
						DrawLine(debugSprite.graphics, provinceHolderA.x, provinceHolderA.y, provinceHolderB.x, provinceHolderB.y);
				}
			}
			
		}
		
		
		public function AddArmy(provinceUid:String,armyModel:Army,armyController:ArmyController):ArmyIcon
		{
			var provHolder:Sprite = GetProvinceHolder(provinceUid);
			var armyIcon:ArmyIcon = new ArmyIcon(armyModel,armyController);
			provHolder.addChild(armyIcon);
			armyIcon.papa = this;
			
			
			armies.push(armyIcon);
			
			return armyIcon;
		}
		
		public function RemoveArmy(armyView:ArmyIcon):void
		{
			if (armyView.parent)
				armyView.parent.removeChild(armyView);
			
			armies.splice(armies.indexOf(armyView),1 );
			
			armyView.papa = null;
		}
		
		public function GetProvinceHolder(uid:String):Sprite
		{
			for (var i:int = 0; i < provinceHolders.length; i++)
			{
				if (provinceHolders[i].uid == uid)
					return provinceHolders[i].sprite;
			}
			return null;
		}
		
		public function SelectProvinceToMarch(fromProvinceUid:String,callback:Function):void
		{
			spriteHolder.mouseChildren = false;
			spriteHolder.mouseEnabled = false;
			
			//get neighbors
			var provinces:Array = mapInfo.GetProvince(fromProvinceUid).routes.slice();
			
			var cmd:SelectProvinceToMoveCommand = new SelectProvinceToMoveCommand(this, fromProvinceUid,provinces, callback);
			cmd.papa = this;
			cmd.callback = OnSelectProvincesToFinish;
			cmd.Execute();
		}
		
		public function SelectProvinceToRaid(fromProvinceUid:String,callback:Function):void
		{
			spriteHolder.mouseChildren = false;
			spriteHolder.mouseEnabled = false;
			
			//get neighbors
			var provinces:Array = mapInfo.GetProvince(fromProvinceUid).routes.slice();
			
			var cmd:SelectProvinceToRaidCommand = new SelectProvinceToRaidCommand(this, fromProvinceUid, provinces, callback);
			cmd.papa = this;
			cmd.callback = OnSelectProvincesToFinish;
			cmd.Execute();
		}
		
		public function SelectProvinceToSupport(fromProvinceUid:String,callback:Function):void
		{
			spriteHolder.mouseChildren = false;
			spriteHolder.mouseEnabled = false;
			
			//get neighbors
			var provinces:Array = mapInfo.GetProvince(fromProvinceUid).routes.slice();
			
			var cmd:SelectProvinceToSupportCommand = new SelectProvinceToSupportCommand(this, fromProvinceUid, provinces, callback);
			cmd.papa = this;
			cmd.callback = OnSelectProvincesToFinish;
			cmd.Execute();
		}		
		
		private function OnSelectProvincesToFinish():void
		{
			spriteHolder.mouseChildren = true;
			spriteHolder.mouseEnabled = true;
			
		}
		
		public function DrawLine(graphics:Graphics, x1:Number, y1:Number, x2:Number, y2:Number, c:uint = 0xFFFFFF, t:Number = 10.0, a:Number = 0.25):void
		{
			graphics.lineStyle(t, c, a);
			graphics.moveTo(x1, y1);
			graphics.lineTo(x2, y2);
		}
		
		public function SetArmiesMouseListeners(orly:Boolean):void
		{
			spriteHolder.mouseChildren = spriteHolder.mouseEnabled = orly;
		}
		
		public function LockPlayerArmies(playerUid:int,orly:Boolean):void
		{
			for each (var army:ArmyIcon in armies) 
			{
				if (army.controller.loyalty == playerUid)
					army.mouseChildren = army.mouseEnabled = !orly;
			}
		}
		
		public function LockArmies(orly:Boolean,playerUid:int,all:Boolean=false):void
		{
			if (!all)
				LockPlayerArmies(playerUid, orly);
			else
			{
				for (var i:int = 0; i < papa.players.length; i++) 
				{
					LockPlayerArmies(papa.players[i].uid, orly);
				}
			}
		}
		
	}

}